[9] 檔案讀寫 + 例外處理


Posted by bessyhuang on 2023-06-09

檔案讀寫

建立檔案物件:open(file, mode)

open(file, mode='r', encoding=None)
💡 四種開啟檔案的方法: r(Default), w, a, x
💡 指定處理的檔案類型: t(Default), b
    t(text mode) e.g. texts
    b(binary mode) e.g. images

f = open("demofile.txt", "rt")
f = open("demofile.txt")       # 等同上面
  • 使用 open() 函式建立 檔案物件
    • 無論是寫檔或讀檔,都必須透過中介的檔案物件。
    • 檔案指標 (file pointer) 用來指向目前讀取或寫入到哪個位置。
  • 語法
    • file:設定欲存取的檔案,包含檔案的路徑及名稱。
    • mode:設定檔案物件的存取模式。
    • encoding="utf-8"
  • 範例

      fileObj1 = open("/Users/bessyhuang/Downloads/Python_test/test.txt", "r")
      # 檔案不存在,出現 FileNotFound 錯誤。
    
      fileObj2 = open("/Users/bessyhuang/Downloads/Python_test/test.txt", "w")
      # Success! 檔案不存在,就會建立檔案。
    

file:檔案路徑與表示方式

  • 檔案路徑
    • 絕對路徑:即這個檔案 最完整 的路徑。
    • 相對路徑:即 相對於目前編寫 Python Script 的路徑。
      • /:根目錄
      • ./:當前同級目錄
      • ../:上級目錄
  • 檔案路徑表示方式

    • Windows

        ## 方法一:使用跳脫字元 \\ 來表示 \
        fileObj1 = open("C:\\Users\\pcsh1\\Music\\test.txt", "w")
      
        ## 方法二:在絕對路徑前面加上 r ,表示此字串為原始字串
        fileObj2 = open(r"C:\Users\pcsh1\Music\test2.txt", "w")
      
    • MacOS / Linux
        fileObj1 = open("/Users/bessyhuang/Downloads/Python_test/test.txt", "w")
      

mode:檔案讀寫的模式

💡 注意!
    r:若檔案不存在,就會發生錯誤 (FileNotFoundError)。
    w:會先清除原檔案內容,再從檔案開頭開始重新寫入。

寫入檔案 - 3 步驟

# 開啟檔案
fileObj = open(r"C:\Users\pcsh1\Music\test1.txt", "w")

# 寫入檔案
fileObj.write("登金陵鳳凰台")

# 關閉檔案
fileObj.close()

讀取檔案 - 3 步驟

# 開啟檔案
fileObj = open(r"C:\Users\pcsh1\Music\test1.txt", "r")

# 讀取檔案: read()、 readline()、 readlines()
content = fileObj.read() 
print(content)

# 關閉檔案
fileObj.close()

read()

read([n])
  • 語法

    • read([n]):讀取 n 個文字,然後傳回該字串。
    • read():n 省略不寫,傳回檔案的 所有資料

      fileObj = open(r"C:\Users\pcsh1\Music\test1.txt", "r")
      
      # read() 可以指定讀取幾個文字。
      str1 = fileObj.read(3)
      print(str1)                 # 登金陵 
      
      content = fileObj.read()  
      print(content)
      
      fileObj.close()
      

readline()

readline()
  • 語法

    • 從檔案 讀取一行 資料,然後傳回該字串。
    • 若傳回空字串,表示抵達檔案結尾。

      fileObj = open("C:\\Users\\pcsh1\\Music\\test1.txt", "r")
      
      line = fileObj.readline()        # 讀取一行
      while line != '':
        print(line)
        line = fileObj.readline()    # 讀取下一行
      
      fileObj.close()
      

readlines()

readlines()
  • 語法

    • 讀取所有行,再 以 list 形式傳回所有行

      fileObj = open(r"C:\Users\pcsh1\Music\test1.txt", "r")
      
      content = fileObj.readlines()      # 讀取所有行
      print(content)  
      # ['登金陵鳳凰台\n', '鳳凰臺上鳳凰遊,鳳去臺空江自流。\n', '吳宮花草埋幽徑,晉代衣冠成古丘。\n', '三山半落青天外,二水中分白鷺洲。\n', '總為浮雲能蔽日,長安不見使人愁。']
      
      for line in content:
        print(line)
      
      fileObj.close()
      

補充:with 敘述 👍

with open(*file*, *mode*) as FileName:
    [Statement]

with open("test.txt", "r") as fileObj:
    content = fileObj.readlines()
  • 先前作法:
    • 存取檔案結束後, 必須呼叫 close() 關閉檔案物件,否則檔案會被鎖定。
    • 補充:如果沒有 呼叫 close() 關閉檔案物件,可能會出事! [Ref 4]
  • with 敘述 作法:
    • 一旦程式的執行離開區塊,就自動關閉檔案物件,故 無須呼叫 close()

例外處理

💡 例外處理的使用時機:
    - 執行程式可能會出現 Error message,但仍想要讓程式繼續執行。
        e.g. 預測某段程式「可能」會有怎樣的錯誤,所以才放上 try ... except

    - 針對不同的 Error message,紀錄 Error message (log),並進行相應的例外處理。

try ... except

💡 建議的完整寫法:

try:
    [Statement]
except:
    [Statement] -> Handle error message statement
else:
    [Statement] -> Do it when try block success
finally:
    [Statement] -> Do it no matter try and except block success or not

使用 try ... except 處理因應使用者錯誤輸入、網路斷線、語法上的問題...等而造成的程式終止的異常。

如果沒有 try ... except 處理這些異常,程式會立即中止,並出現 Error message。

  • 語法
    • try 區塊:嘗試執行的程式區塊,允許出現 Error。
    • except 區塊:當 try 區塊執行出錯時,會執行 except 區塊,進行 Error message 的處理。
    • else 區塊:執行 try 區塊 沒有出現 Error message 時,會執行 else 區塊
    • finally 區塊:無論 try ... except 區塊是否出現 Error message 都會執行

範例

  • try ... except ... else

      try:
          a = 1 / 0
      except NameError as ne:
          print("Input Error !!!")
          print(ne)
      except ZeroDivisionError as ze:
          print("ZeroDivisionError ~")
          print(ze)
      else:
          print(a)
    
      # x = 2
    
      try:
          print(x)
      except:
          print("Something went wrong")
      else:
          print("The 'try' block can be executed successfully.")
    
  • try ... except
      try:
          # try 區塊中任何一行程式碼報錯,該行程式碼後面的語句就不會執行,並丟擲 Error message。
          file = open('test.txt', 'r')
      except Exception as e:
          # 異常處理
          print(e.args[-1])
          print(e)
      else:
          file.close()
    
  • try ... except ... else ... finally

      # x = 2
    
      try:
          print(x)
      except:
          print("Something went wrong")
      else:
          print("The 'try' block can be executed successfully.")
      finally:
          print("The 'try except' is finished.")
    

練習題

資料夾存在與否的例外處理

  • 條件
    • 輸入 資料夾名稱 (e.g. Python_test ),接著進行以下判斷:
      • 當前目錄若存在 Python_test 資料夾的話,就輸出 資料夾已存在。
      • 當前目錄若不存在 Python_test 資料夾的話,就輸出 建立 Python_test 資料夾
  • Hint:
    • 取得當前目錄位置 os.getcwd()
    • 建立資料夾 os.mkdir(path)
    • 判斷資料夾存在與否 FileExistsError
  • 輸入
      Please input the folder name: (e.g. Python_test)
      > Python_test
    
  • 輸出
    • 資料夾尚未存在
        Current path: /Users/bessyhuang/Downloads
        FILE_NAME 'Python_test' created
        File path: /Users/bessyhuang/Downloads/Python_test
      
    • 資料夾已存在
        Current path: /Users/bessyhuang/Downloads
        資料夾已存在。
        File path: /Users/bessyhuang/Downloads/Python_test
      

讀寫詩句 + 計算各詞彙的出現頻率

  • 條件
    • 輸入 資料夾名稱 (e.g. Python_test ),接著進行以下判斷:
      • 當前目錄若存在 Python_test 資料夾的話,就輸出 資料夾已存在。
      • 當前目錄若不存在 Python_test 資料夾的話,就輸出 建立 Python_test 資料夾
    • 在該資料夾下建立 poem.txt,並進行以下動作:
      • 輸入詩句,並將詩句寫入 poem.txt
      • 計算詩詞中每個單字的出現次數,並再次寫入檔案中。
          PS. 標點符號的次數,不能列入計算。
        
  • 輸入

      Please input the folder name: (e.g. Python_test)
      > Python_test
    
      Please input the english poem:
      > If you shed tears when you miss the sun, you also miss the stars.
    
  • 輸出

    • 資料夾尚未存在
        Current path: /Users/bessyhuang/Downloads
        FILE_NAME 'Python_test' created
        File path: /Users/bessyhuang/Downloads/Python_test
      
    • 資料夾已存在
        Current path: /Users/bessyhuang/Downloads
        資料夾已存在。
        File path: /Users/bessyhuang/Downloads/Python_test
      
    • poem.txt 檔案內容

        💡 目錄階層的示意圖
        ~/Downloads » tree Python_test                       
        Python_test
        └── poem.txt
      
        0 directories, 1 file
      
        If you shed tears when you miss the sun you also miss the stars
        {'If': 1, 'you': 3, 'shed': 1, 'tears': 1, 'when': 1, 'miss': 2, 'the': 2, 'sun': 1, 'also': 1, 'stars': 1}
      

References

  1. Python open()
  2. Python File Open
  3. Python學習日誌-檔案讀取、寫入、模式比較(r+、a+、w+)
  4. python file.close()的重要性
  5. Python Built-in Exceptions(錯誤類型):Python Errors and Built-in Exceptions

#Python #File I/O #TryExcept







Related Posts

Vue - Object.defineProperty & Proxy

Vue - Object.defineProperty & Proxy

VS code 段落過長怎麼辦?

VS code 段落過長怎麼辦?

基礎 PHP & MySQL 資料庫

基礎 PHP & MySQL 資料庫


Comments